package be.donovan.gui.helper;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.beans.PropertyVetoException;

import javax.swing.ImageIcon;
import javax.swing.JDesktopPane;
import javax.swing.JDialog;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.ToolTipManager;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import be.donovan.gui.MenuController;
import be.donovan.gui.QuebakMenuBar;
import be.donovan.gui.helper.components.AbstractController;
import be.donovan.gui.helper.components.MVCFrame;
import be.donovan.gui.helper.components.StatusBar;
import be.donovan.gui.helper.components.ViewI;


/**
 * This is the "main" class of the application ATDL3 It implements Runnable
 * because we need a thread to hold the context of the SecurityContextHolder.
 * 
 * @author BE-MIL-CCCIS-ATDL3
 * 
 */
public class MainFrame extends MVCFrame implements InitializingBean {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1706227676465762834L;

	private static final ImageIcon FRAME_ICON = ImageLoader.getImageIcon("splash.jpg");

	public static ClassPathXmlApplicationContext context;

	public JToolBar applicationJToolBar = new JToolBar();

	public BorderLayout layout = null;

	public JDialog frame;

	public static final MainFrame instance = new MainFrame();

	// icon of the frame
	public static final Image APPLICATION_FRAME_ICON = ImageLoader.getImageIcon("splash.jpg").getImage();

	// define the screen dimension

	public Dimension screenDimension = new Dimension(1024, 768);

	private JDesktopPane desktop;

	public static void main(String[] args) throws Exception {
		Starter.getInstance();
	}

	private MainFrame() {
		initFrame();
		initGUI();
	}

	private void initFrame() {
		frame = new JDialog();
		frame.setTitle("Refreshing");
		JLabel label = new JLabel();
		label.setIcon(ImageLoader.getImageIcon("propeller.GIF"));
		label.setVisible(true);
		label.setHorizontalAlignment(JLabel.CENTER);
		frame.getContentPane().add(label);
		frame.setModal(false);
		frame.pack();		
		Dimension dimension = frame.getPreferredSize();
		int i = dimension.height;
		int j = dimension.width;
		Dimension temp = Toolkit.getDefaultToolkit().getScreenSize();
		frame.setLocation(temp.width / 2 - j / 2, temp.height / 2 - i / 2);
	}

	private void initGUI() {
		// This method initialize the application frame.
		// set the layout : borderlayout
		// set a toolBar : ApplicationJToolBar
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setTitle(InfoProvider.getApplicationVersion());
		layout = new BorderLayout();
		this.setLayout(layout);
		this.add(applicationJToolBar, BorderLayout.NORTH);
		this.setIconImage(FRAME_ICON.getImage());
		this.add(new StatusBar(), BorderLayout.SOUTH);
		QuebakMenuBar quebakMenuBar = new QuebakMenuBar();
		quebakMenuBar.setMenuController(new MenuController());
		quebakMenuBar.getController().start();
		this.setJMenuBar(quebakMenuBar);
		this.setSize(screenDimension);
		this.setExtendedState(Frame.MAXIMIZED_BOTH);
		desktop = new JDesktopPane();
		add(desktop, BorderLayout.CENTER);
		desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
		desktop.setDoubleBuffered(true);

	}

	@Override
	public Component add(final Component component) {
		// for (JInternalFrame internalFrame : desktop.getAllFrames()) {
		// try {
		// internalFrame.setMaximum(false);
		// } catch (PropertyVetoException e2) {
		// // TODO Auto-generated catch block
		// e2.printStackTrace();
		// }
		// if (internalFrame.getTitle().equals(component.getName())) {
		// try {
		// Dimension screenSize = desktop.getSize();
		// internalFrame.setMaximum(false);
		// internalFrame.setLocation((screenSize.width / 2)
		// - (internalFrame.getSize().width / 2),
		// (int) ((screenSize.height / 2) - (internalFrame
		// .getSize().getHeight() / 2)));
		// internalFrame.moveToFront();
		// internalFrame.setSelected(true);
		// return component;
		// } catch (PropertyVetoException e1) {
		// }
		// }
		// }
		final JInternalFrame dialog = new JInternalFrame(component.getName(), true, true, true, true);
		dialog.setFrameIcon(FRAME_ICON);
		if (component instanceof ViewI) {
			((ViewI) component).getController().doDeferredLayout();
		}

		dialog.setSize((int) component.getPreferredSize().getWidth() + 15, (int) component.getPreferredSize().getHeight() + 40);
		Dimension screenSize = desktop.getSize();
		dialog.setMaximumSize(screenSize);
		dialog
				.setLocation(
						((screenSize.width / 2) - (dialog.getSize().width / 2) > 0 ? (screenSize.width / 2)
								- (dialog.getSize().width / 2) : 0),
						(int) ((screenSize.height / 2) - (dialog.getSize().getHeight() / 2)) > 0 ? (int) ((screenSize.height / 2) - (dialog
								.getSize().getHeight() / 2))
								: 0);

		dialog.addInternalFrameListener(new InternalFrameAdapter() {
			@Override
			public void internalFrameClosing(InternalFrameEvent e) {
				if (((ViewI) component).getController() != null) {
					((ViewI) component).getController().stop();
				} else {
					dialog.dispose();
				}
				// persistState(component);
				super.internalFrameClosing(e);
			}

			@Override
			public void internalFrameActivated(InternalFrameEvent e) {
				super.internalFrameActivated(e);
				e.getInternalFrame().requestFocusInWindow();
			}

		});
		dialog.addComponentListener(new ComponentAdapter() {

			@Override
			public void componentResized(ComponentEvent e) {
				super.componentResized(e);
				dialog.setToolTipText(dialog.getSize().width + "," + dialog.getSize().height);
				ToolTipManager.sharedInstance().registerComponent(dialog);
				System.err.println(dialog.getToolTipText());
			}

		});

		
		dialog.addKeyListener(new KeyListener(){

			public void keyPressed(KeyEvent e) {
				if(e.getKeyCode() == KeyEvent.VK_F5){					
					if(component instanceof ViewI){
						frame.setVisible(true);						
						dialog.setCursor(new Cursor(Cursor.WAIT_CURSOR));
						((ViewI) component).getController().refresh();
						dialog.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
						frame.setVisible(false);
					}
				}
			}

			

			public void keyReleased(KeyEvent e) {				
			
			}

			public void keyTyped(KeyEvent e) {
				
			
			}
			
		});
		
		component.setVisible(true);
		dialog.getContentPane().setLayout(new BorderLayout());
		dialog.getContentPane().add(new JScrollPane(component),
				BorderLayout.CENTER);
		desktop.add(dialog);
		dialog.setVisible(true);
		// dialog.requestFocus();
		try {
			if (dialog.getSize().height + 15 > screenSize.height || dialog.getSize().width > screenSize.width) {
				dialog.setMaximum(true);
				dialog.setSelected(true);
			} else {
				dialog.setMaximum(false);
				dialog.setSelected(true);
			}

		} catch (PropertyVetoException e2) {
			e2.printStackTrace();
		}
		dialog.requestFocusInWindow();
		return dialog;
	}

	@SuppressWarnings("unchecked")
	public AbstractController<MainFrame> getController() {
		return controller;
	}

//	private void persistState(Component component) {
//		File file = new File(getComponentStateFileName(component));
//		XMLEncoder e;
//		try {
//			e = new XMLEncoder(new BufferedOutputStream(new FileOutputStream(file)));
//			e.writeObject(component);
//			e.close();
//		} catch (FileNotFoundException e1) {
//			// TODO Auto-generated catch block
//			e1.printStackTrace();
//		}
//	}

//	private String getComponentStateFileName(Component component) {
//		return System.getProperty("java.io.tmpdir") + File.separatorChar + component.getName() + ".state";
//	}

	public static MainFrame getInstance() {
		return instance;
	}

}
